<template>
  <div class="sub-table">
    <PageableTable
      ref="table"
      auto-height
      :data="rows"
      :api="fetchApi"
      :show-summary="showSummary"
      :selection-width="selectionWidth"
      v-bind="$attrs"
      hide-on-single-page
      :selection="selection"
      v-on="$listeners"
      @selection-change="onSelectionChange">
      <!--顶部工具栏-->
      <template v-if="!inputDisabled || hasToolBarMenu" #toolbar>
        <div class="table-header flex-row">
          <slot name="toolbar" :add-row="addRow" :del-row="delRow" :refresh="refresh">
            <div class="flex-item">
              <slot name="toolbar-left" :add-row="addRow" :del-row="delRow" :refresh="refresh">
                <ElButton
                  v-if="toolbarMenus?.includes('add')"
                  size="mini"
                  class="table-header-button add"
                  icon="el-icon-circle-plus"
                  type="text"
                  @click="addRow">
                  添加
                </ElButton>
                <ConfirmButton
                  v-if="toolbarMenus?.includes('delete')"
                  size="mini"
                  :disabled="selectedRows.length <= 0"
                  class="table-header-button remove"
                  message="您确定要删除选中的记录吗？"
                  icon="el-icon-error"
                  type="text"
                  @click="delRow">
                  删除
                </ConfirmButton>
                <ElButton
                  v-if="toolbarMenus?.includes('refresh')"
                  size="mini"
                  class="table-header-button refresh"
                  icon="el-icon-refresh-left"
                  type="text"
                  :disabled="false"
                  @click="refresh">
                  刷新
                </ElButton>
              </slot>
            </div>
            <div class="flex-not-shrink">
              <slot name="toolbar-right"> </slot>
            </div>
          </slot>
        </div>
      </template>
      <!--表格列-->
      <slot name="columns" :columns="columns">
        <template v-for="item in columns">
          <TableColumn
            v-if="item.label && !item.hide && !item.slot"
            :key="`${item.prop}-${enabled}${item.type ? `-${item.type}` : ''}`"
            :label="item.label"
            :width="item.width"
            :align="item.align"
            :prop="item.prop"
            :options="item.options"
            :show-overflow-tooltip="!enabled && item.showOverflowTooltip">
            <!--列头-->
            <template #header> <span v-if="!inputDisabled && item.required" style="color: #f56c6c">*</span>{{ item.label }} </template>
            <!--列内容-->
            <template #default="{ row, column, $index }">
              <!--tag 插槽-->
              <slot name="tag" :row="row" :column="column" :index="$index"></slot>
              <!--列默认插槽,名字和 prop 保持一致-->
              <slot :row="row" :column="column" :index="$index" :prop="`${prop}[${$index}].${item.prop}`" :required="item.required" :name="item.prop">
                <template v-if="enabled && item.editable === true">
                  <template v-if="getCellType(row, item) === 'input'">
                    <FormInput
                      :value="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      @input="val => onInput(row, val, item)" />
                  </template>
                  <template v-else-if="getCellType(row, item) === 'inputPhoneNumber'">
                    <FormInputPhoneNumber
                      :value="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      @input="val => onInput(row, val, item)" />
                  </template>
                  <template v-else-if="getCellType(row, item) === 'user'">
                    <FormInputUser
                      v-if="item.single"
                      :is-user-check="isUserCheck"
                      :name.sync="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      @input="val => onInput(row, val, item)" />
                    <FormInputUser
                      v-else
                      :is-user-check="isUserCheck"
                      :value="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      @input="val => onInput(row, val, item)" />
                  </template>
                  <template v-else-if="getCellType(row, item) === 'department'">
                    <FormInputDepartment
                      v-if="item.single"
                      :ou-type="item.ouType"
                      :name.sync="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      @input="val => onInput(row, val, item)" />
                    <FormInputDepartment
                      v-else
                      :value="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      @input="val => onInput(row, val, item)" />
                  </template>
                  <template v-else-if="getCellType(row, item) === 'select'">
                    <FormSelect
                      :value="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      @input="val => onInput(row, val, item)" />
                  </template>
                  <template v-else-if="getCellType(row, item) === 'datePicker'">
                    <FormDatePicker
                      :value="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      :start.sync="row[item.start]"
                      :end.sync="row[item.end]"
                      @input="val => onInput(row, val, item)" />
                  </template>
                  <template v-else-if="getCellType(row, item) === 'cascader'">
                    <FormCascader
                      :value="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      :label-key="item.labelKey"
                      :value-key="item.valueKey"
                      @input="val => onInput(row, val, item)" />
                  </template>
                  <template v-else-if="getCellType(row, item) === 'checkbox'">
                    <FormCheckboxGroup
                      :value="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      @input="val => onInput(row, val, item)" />
                  </template>
                  <template v-else-if="getCellType(row, item) === 'number'">
                    <FormInputNumber
                      :value="row[column.property]"
                      v-bind="getInputAttr(row, item)"
                      :disabled="isInputDisabled(row, item)"
                      :prop="`${prop}[${$index}].${item.prop}`"
                      :required="item.required"
                      @input="val => onInput(row, val, item)" />
                  </template>
                </template>
                <template v-else-if="item.dicType || item.options?.length">
                  <DictRender :dict-type="item.dicType" :column="column" :row="row" :options="item.options" />
                </template>
                <template v-else>{{ getVal(row, column, item) }}</template>
              </slot>
            </template>
          </TableColumn>
          <!--列自定义插槽,名字和 prop 不一致-->
          <slot v-else-if="item.slot" :name="item.slot"></slot>
        </template>
      </slot>
      <slot :add="add" :remove="remove" name="handle"></slot>
      <!--操作列-->
      <TableColumn v-if="!inputDisabled && hasHandleMenus" label="操作" fixed="right" width="80" align="center" prop="menu">
        <!--表头-->
        <template #header="{ column, $index }">
          <slot name="handle-column-header" :column="column" :index="$index">
            {{ column.label }}
          </slot>
        </template>
        <!--操作-->
        <template #default="{ row, $index }">
          <i
            v-if="handleMenus?.includes('add') && value?.length < limit"
            class="el-icon-circle-plus sub-table-handle-button table-button-add"
            style="margin-right: 5px; font-size: 20px; cursor: pointer"
            title="添加"
            @click.stop="add(row, $index)"></i>
          <Confirmable
            v-if="handleMenus?.includes('delete')"
            class="el-icon-error sub-table-handle-button table-button-remove"
            title="删除"
            message="您确定要删除该行吗？"
            @click.stop="remove(row, $index)" />
        </template>
      </TableColumn>
      <!--底部添加按钮-->
      <template v-if="bottomAddButton" #empty>
        <i
          class="el-icon-circle-plus sub-table-handle-button table-button-add"
          style="font-size: 20px; cursor: pointer"
          title="添加"
          @click.stop="add(null, -1)"></i>
      </template>
    </PageableTable>
    <!--底部添加按钮-->
    <div
      v-if="!inputDisabled && bottomAddButton && value?.length < limit && value?.length > 0"
      class="flex-row vertical-center horizon-center"
      style="padding: 10px; border: 1px solid #ebeef5; border-top: none">
      <i
        class="el-icon-circle-plus sub-table-handle-button table-button-add"
        style="font-size: 20px; cursor: pointer"
        title="添加"
        @click.stop="add(null, -1)"></i>
    </div>
  </div>
</template>

<script>
  import { findTreeChildren, isFunction } from '@web-utils/core'
  import { cloneDeep } from '@web-utils/integrations/lodash'
  import SubTablePlusProps from '@/components/table/sub-table-plus-props'

  export default {
    name: 'SubTablePlus',
    mixins: [SubTablePlusProps],
    inject: {
      elForm: {
        default: ''
      },
      elFormItem: {
        default: ''
      }
    },
    data() {
      return {
        rows: [],
        selectedRows: []
      }
    },
    computed: {
      enabled() {
        return !this.inputDisabled
      },
      hasToolBarMenu() {
        return this.toolbarMenus?.length
      },
      hasHandleMenus() {
        return this.handleMenus?.length
      },
      rowProps() {
        const props = {}
        if (!this.columns) {
          return props
        }
        this.columns
          .map(value => value.prop)
          .forEach(key => {
            props[key] = null
          })
        return props
      },
      inputDisabled() {
        return this.disabled || (this.elForm || {}).disabled
      }
    },
    watch: {
      value: {
        deep: true,
        immediate: true,
        handler(newVal) {
          this.rows = newVal || []
        }
      },
      rows: {
        deep: true,
        immediate: true,
        handler(newVal) {
          this.$emit('input', newVal)
        }
      }
    },
    methods: {
      getCellType(row, item) {
        if (isFunction(item.getType)) {
          return item.getType(row, item)
        } else {
          return item.type
        }
      },
      getInputAttr(row, item) {
        return { ...item.attrs, ...(item.getAttrs ? item.getAttrs(row) : {}) }
      },
      isInputDisabled(row, item) {
        return item.isDisabled?.(row)
      },
      onInput(row, val, item) {
        if (item.setValue) {
          item.setValue(row, val, item, this.rows)
        } else {
          row[item.prop] = val
        }
      },
      onSelectionChange(selectedRows) {
        this.selectedRows = selectedRows
      },
      async remove(row, index) {
        try {
          this.rows.splice(index, 1)
        } catch (e) {}
      },
      add(row, index) {
        const newRow = cloneDeep(this.rowProps)
        this.initRow?.(newRow)
        if (index === -1) {
          this.rows.push(newRow)
        } else {
          this.rows.splice(index + 1, 0, newRow)
        }
      },
      addRow() {
        this.$emit('add-row')
      },
      async delRow() {
        if (!this.selectedRows.length) {
          this.$message.warning('请选择要删除的记录！')
          return
        }
        try {
          if (this.delApi) {
            try {
              await this.delApi(this.selectedRows.map(value => value.id).join(','))
              this.refresh()
            } catch (e) {
              this.$message.error('删除失败！')
            }
          } else {
            this.$emit(
              'input',
              this.rows.filter(value => !this.selectedRows.includes(value))
            )
          }
          this.$message.success('删除成功！')
        } catch (e) {}
      },
      refresh() {
        this.$refs.table.getPage()
      },
      getVal(row, column, item) {
        if (item.type === 'select' && item.attrs?.options) {
          const option = item.attrs.options.find(v => v.code === row[column.property])
          if (option) {
            return option.name
          }
        }

        if (item.type === 'cascader' && item.attrs?.options) {
          const [option] = findTreeChildren(item.attrs.options, node => node[item.attrs.valueKey || 'value'] === row[column.property])
          if (option) {
            return option[item.attrs.valueKey || 'label']
          }
        }

        return row[column.property]
      }
    }
  }
</script>

<style lang="scss">
  .sub-table {
    .pageable-table.auto-height {
      .el-table {
        min-height: 0;
      }
    }

    .el-form-item {
      width: 100%;
      margin-bottom: 0;
    }

    .el-col {
      width: 100%;
    }

    .table-header {
      padding: 2px 10px;
      background-color: rgba(243, 245, 251, 1);
      border: 1px solid rgba(223, 230, 236, 1);
      border-bottom: none;
    }

    .table-header-button {
      &:hover,
      &:focus {
        color: #595959;
      }

      i + span {
        margin-left: 0;
      }

      i {
        font-size: 15px;
      }

      &.add {
        i {
          color: #4886ec;
        }
      }

      &.remove {
        i {
          color: #e34e55;
        }
      }

      &.refresh {
        i {
          color: #1eb91e;
        }
      }
    }

    .table-button-add {
      color: #5add7a;
      opacity: 0.8;

      &:hover {
        opacity: 1;
      }
    }

    .table-button-remove {
      color: #ddd;

      &:hover {
        color: #ef6666;
      }
    }

    .el-table__header-wrapper {
      .el-table__header {
        th {
          padding: 5px 0;
          background-color: rgba(243, 245, 251, 1);
        }
      }
    }

    .el-table {
      border-top-color: rgb(221, 225, 229);

      td {
        border-color: rgb(223, 230, 236);
      }
    }

    .el-col {
      padding: 0 !important;
    }

    .row-indicator {
      position: absolute;
      top: -6px;
      right: -6px;
      display: inline-block;
      width: 0;
      height: 0;
      border: 6px solid;
      border-color: transparent transparent #f5690c;
      transform: rotate(45deg);
    }

    .sub-table-handle-button {
      font-size: 20px;
      cursor: pointer;

      + .sub-table-handle-button {
        margin-left: 5px;
      }
    }

    .el-table .el-table__header th {
      padding: 5px 0;
      line-height: inherit;
      background: #f3f5fb !important;
    }
  }
</style>
